#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>


// 子线程任务函数 --- 接收信息
void * recv_msg(void* arg)        
{
    // 1、将自身设置为分离属性(此线程函数结束后，自动有人给它收尸)
    pthread_detach(pthread_self());     // pthread_self函数可以获取自己的线程id

    // 2、转换参数的类型
    int *p = (int*)arg;

    // 3、正常运行的线程功能(接收来自于服务端发过来的信息)
    while (1)
    {
        // 接收信息
        char buf[1024] = {0};
        read(*p, buf, sizeof(buf));    // 从txt2_fd文件描述符中，读取128个字节的数据，放到read_buf里面
        printf("从服务端收到的信息为 = %s\n", buf);

        if(strncmp(buf, "byebye", 6) == 0)
             pthread_exit(NULL);
    }
}

// 主线程任务函数 --- 发送信息
int main(int argc, char const *argv[])
{
    // 1、创建TCP客户端通信对象(a、买了一部手机)
    int tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (tcp_socket < 0)
    {
        perror("创建TCP客户端通信对象失败!\n");
        return -1;
    }
    
    // 使套接字sockfd关联的地址在套接字关闭后立即释放
    int on = 1;
    setsockopt(tcp_socket, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));  //开启端口复用功能 

    // 2、绑定信息(b、填写自己的信息,并插卡进去)(客户端可以不写，系统会自动帮你设置)

    // 3、填写服务端的信息(c、输入女朋友的电话信息)
    // struct sockaddr *addr;                           // 旧地址结构体，已经废弃掉了
    struct sockaddr_in addr;                            // 创建一个服务器地址结构体
    addr.sin_family      = AF_INET;                     // 设置地址族为IPv4
    addr.sin_port        = htons(8080);                 // 设置端口号为8080
    addr.sin_addr.s_addr = inet_addr("192.168.10.1");   // 设置IP地址为192.168.9.1

    // 4、链接服务端(d、打电话给女朋友)
    int ret_c = connect(tcp_socket, (struct sockaddr *)&addr, sizeof(addr));
    if (ret_c < 0)
    {
        perror("连接服务器失败\n");
        return -2;
    }
    else
    {
        printf("连接结服务器成功!\n");
        // 子线程(听筒)：
        pthread_t recv_msg_ptid;
        pthread_create(&recv_msg_ptid, NULL , recv_msg, (void *)&tcp_socket);
    }

    // 5、主线程(发声孔): 发送信息给服务器(e、和女朋友说话)
    while (1)
    {
        char buf[1024] = {0};
        printf("请输入要发送给服务端的信息:\n");
        scanf("%s", buf);
        
        write(tcp_socket, buf, strlen(buf));
        if(strncmp(buf, "byebye", 6) == 0)
            break;
    }

    // 6、关闭通信(f、挂断女朋友的电话)
    close(tcp_socket);

    return 0;
}

